package com.mlnx.device.service.impl;

import com.alibaba.fastjson.JSON;
import com.mlnx.device.dao.mongodb.DeviceStateDao;
import com.mlnx.device.pojo.dto.DeviceStateRecord;
import com.mlnx.device.service.DeviceStateService;
import com.mlnx.mptp.model.DeviceState;
import com.mlnx.service.common.utils.DateUtils;
import com.mlnx.tp.base.utils.LogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;

/**
 * Created by amanda.shan on 2019/11/26.
 */
@Service
public class DeviceStateServiceIml implements DeviceStateService {

    @Autowired
    private DeviceStateDao deviceStateDao;

    @Override
    public void saveDeviceState(DeviceStateRecord deviceStateRecord) {
        deviceStateDao.save(deviceStateRecord);
    }

    @Override
    public Map<String, Object> getEcgMarks(Date startTime, Date endTime, Integer patientId) {
        Map<String, Object> map = new HashMap<String, Object>();
        String sign = "0";//0:可信；1:不可信

        boolean today = false;
        Date now = new Date();
        Date sTime = startTime;
        Date eTime;
        if (endTime.getTime() > now.getTime()) {
            eTime = now;
            today = true;
        } else
            eTime = endTime;

        List<DeviceStateRecord> list;
        List<DeviceStateRecord> listAll = new ArrayList<>();
        DeviceStateRecord tempRecord = new DeviceStateRecord();
        try {
            list = deviceStateDao.selectOnOffLine(sTime, eTime, patientId);

            int last = 0; //0:未知；1：开始；2：结束
            for (DeviceStateRecord dor : list) {
                // LogUtils.d(dor.toString());
                if ("DEVICE_ONLINE".equals(dor.getDeviceState().name())) {
                    if (last != 1) {
                        listAll.add(dor);
                        last = 1;
                    }
                } else {
                    switch (last) {
                        case 0:
                            tempRecord.setDate(sTime);
                            tempRecord.setDeviceState(DeviceState.DEVICE_ONLINE);
                            tempRecord.setPatientId(dor.getPatientId());
                            tempRecord.setDeviceId(dor.getDeviceId());
                            listAll.add(tempRecord);
                            listAll.add(dor);
                            last = 2;
                            break;

                        case 1:
                            listAll.add(dor);
                            last = 2;
                            break;

                        case 2:
                            listAll.set(listAll.size() - 1, dor);
                            last = 2;
                            break;
                    }
                }
            }

            if (DeviceState.DEVICE_ONLINE.equals(listAll.get(listAll.size() - 1).getDeviceState())) {
                tempRecord.setDate(eTime);
                tempRecord.setDeviceState(DeviceState.DEVICE_OFFLINE);
                listAll.add(tempRecord);

                if (today)
                    sign = "1";
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        map.put(sign, listAll);

        return map;
    }

    @Override
    public List<DeviceStateRecord> getEcgEvents(Date startTime, Date endTime, Integer patientId) {
        return deviceStateDao.selectEcgEvents(startTime, endTime, patientId);
    }

    @Override
    public Set<Date> getEcgExistedDays(Integer year, Integer month, Integer patientId) {
        Set<Date> records = new HashSet<>();
        try {
            Date startTime = DateUtils.getFirstDayOfMonth(year, month);
            Date endTime = DateUtils.getFirstDayOfMonth(year, month + 1);
            Date current = new Date();
            if (endTime.after(current)) {
                endTime = current;
            }

            List<DeviceStateRecord> deviceStateRecords = deviceStateDao.selectOnOffLine(startTime, endTime, patientId);
            System.out.println(JSON.toJSONString(deviceStateRecords));

            List<DeviceStateRecord> resultDatas = group(deviceStateRecords, startTime, endTime);
            for (int i = 0; i < resultDatas.size() / 2; i++) {
                Date onlineDate = resultDatas.get(2 * i).getDate();
                Date offlineDate = resultDatas.get(2 * i + 1).getDate();
                records.add(DateUtils.formatDate(onlineDate));
                while (DateUtils.getFutureDate(onlineDate, 1).before(offlineDate)) {
                    records.add(DateUtils.getFutureDate(onlineDate, 1));
                    onlineDate = DateUtils.getFutureDate(onlineDate, 1);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
            LogUtils.e("日期解析错误:", e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return records;
    }

    public List<DeviceStateRecord> group(List<DeviceStateRecord> list, Date startTime, Date endTime) {

        List<DeviceStateRecord> listOn = new ArrayList<DeviceStateRecord>();
        List<DeviceStateRecord> listOff = new ArrayList<DeviceStateRecord>();
        List<DeviceStateRecord> listAll = new ArrayList<DeviceStateRecord>();

        DeviceStateRecord onDor = new DeviceStateRecord();
        DeviceStateRecord offDor = new DeviceStateRecord();
        DeviceStateRecord deviceStateRecord = new DeviceStateRecord();

        try {
            for (DeviceStateRecord dor : list) {

                if (dor.getDeviceState().equals("DEVICE_ONLINE")) {
                    listOn.add(dor);

                } else {
                    listOff.add(dor);
                }
            }
            if (listOff.size() == 0 && listOn.size() != 0) {
                onDor = listOn.get(0);
                deviceStateRecord.setDate(endTime);
                deviceStateRecord.setDeviceState(DeviceState.DEVICE_OFFLINE);
                deviceStateRecord.setDeviceId(onDor.getDeviceId());
                deviceStateRecord.setPatientId(onDor.getPatientId());
                listAll.add(onDor);
                listAll.add(deviceStateRecord);
            } else if (listOn.size() == 0 && listOff.size() != 0) {
                offDor = listOff.get(0);
                deviceStateRecord.setDate(startTime);
                deviceStateRecord.setDeviceState(DeviceState.DEVICE_ONLINE);
                deviceStateRecord.setDeviceId(offDor.getDeviceId());
                deviceStateRecord.setPatientId(offDor.getPatientId());
                listAll.add(offDor);
                listAll.add(deviceStateRecord);
            } else if (listOn.size() == 0 && listOff.size() == 0) {
            } else {
                for (int i = 0; i < listOn.size(); i++) {
                    if (i == 0) {
                        if (listOn.get(i).getDate().getTime() < (listOff.get(i).getDate().getTime())) {
                            onDor = listOn.get(i);
                            offDor = listOff.get(i);
                            listAll.add(onDor);
                            listAll.add(offDor);
                        } else {
                            onDor = listOn.get(i);
                            deviceStateRecord.setDeviceId(listOn.get(i).getDeviceId());
                            deviceStateRecord.setPatientId(listOn.get(i).getPatientId());
                            deviceStateRecord.setDeviceState(listOn.get(i).getDeviceState());
                            deviceStateRecord.setDate(startTime);
                            offDor = listOff.get(i);
                            listAll.add(deviceStateRecord);
                            listAll.add(offDor);
                            for (int j = 0; j < listOff.size(); j++) {
                                if (listOff.get(j).getDate().getTime() >= (onDor.getDate().getTime())) {
                                    offDor = listOff.get(j);
                                    listAll.add(onDor);
                                    listAll.add(offDor);
                                    break;
                                }
                            }

                        }

                    }
                    if (listOn.get(i).getDate().getTime() >= (offDor.getDate().getTime())) {
                        onDor = listOn.get(i);
                        for (int j = 0; j < listOff.size(); j++) {
                            if (listOff.get(j).getDate().getTime() > (onDor.getDate().getTime())) {
                                offDor = listOff.get(j);
                                listAll.add(onDor);
                                listAll.add(offDor);
                                break;
                            }
                        }
                    }
                }
                for (int m = 0; m < listOn.size(); m++) {//最后是上线设备没有下线
                    if (listOn.get(m).getDate().getTime() >= listAll.get(listAll.size() - 1).getDate().getTime()) {
                        onDor = listOn.get(m);
                        DeviceStateRecord dr = new DeviceStateRecord();
                        dr.setDate(endTime);
                        dr.setDeviceId(listOn.get(m).getDeviceId());
                        dr.setDeviceState(DeviceState.DEVICE_OFFLINE);
                        dr.setPatientId(listOn.get(m).getPatientId());
                        listAll.add(onDor);
                        listAll.add(dr);
                        break;
                    }
                }
            }

            if (listAll.size() == 2) {//只有一组上下线数据取下线设备的最后时间
                offDor = listOff.get(listOff.size() - 1);

                listAll.set(1, offDor);
            } else {
                for (int k = 0; k < listAll.size(); k = k + 2) {//取下线设备的最后时间
                    offDor = listAll.get(k + 1);
                    for (int j = 0; j < listOff.size(); j++) {
                        if (listOff.get(j).getDate().after(offDor.getDate()) && listOff.get(j).getDate().before
                                (listAll.get(k + 2).getDate())) {
                            offDor = listOff.get(j);
                        }
                    }
                    listAll.set(k + 1, offDor);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return listAll;
    }
}
